home *** CD-ROM | disk | FTP | other *** search
- /*
- File: BigEasy.c
-
- Contains: Main Event Loop Processing
-
- Written by: David Van Brink & The Utility Muffin Research Kitchen
-
- Copyright: © 1991-1992 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <9> 4/20/92 JDR Changed the sleep timeout for WaitNextEvent to always be a
- standard time, because we'll poll faster when we're trying to
- play a sound using a FakeInterrupt method which waits for events
- using OSEventAvail.
- <8> 2/26/92 JDR Doing a little clean up. Changed some menus around.
- <7> 2/16/92 JDR Conditional for the Think C MacHeaders or MPW's MacHeaders. Got
- rid of warnings. Needed to add #pragmas to the default routines.
- <6> 1/16/92 JDR Using MacHeaders instead of all those includes to make builds go
- faster.
- <5> 12/4/91 JDR Keep sleeping at zero, for now.
- <4> 11/15/91 JDR Changed the event loop to call idle procs and added a global
- sleep parameter.
- <3> 10/16/91 JDR Changing NewWindow to NewCWindow, added a new GetxxxWindow call,
- and had to change the event handlers a bit
- <2> 9/27/91 KIP Fix DoClose to correctly dispose of all windows in the window
- object list.
- <1> 9/27/91 KIP Change DoQuit to dispose every window in the list.
- To Do:
- */
-
- #ifdef THINK_C
- #include <MacHeaders>
- #else
- #pragma load "MPWHeaders"
- #endif
-
- #define LoMemGrayRgn (* (RgnHandle*) GrayRgn) /* gray region */
- #define LoMemWMgrPort (* (GrafPtr*) WMgrPort) /* WMgrPort */
- #define LoMemROM85 (* (unsigned short*) ROM85) /* ROM version */
- #define HaveCQD() (LoMemROM85 <= 0x3FFF) /* true if color quickdraw is present */
-
- #include "BigEasy.h"
- //#include "SndManager.h"
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Limits
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- #define WMax 30 /* Number of windows in list */
- #define MMax 15 /* Number of menus in menubar */
- #define MIMax 48 /* Number of items per menu */
-
- Rect bigRect = {-16000,-16000,16000,16000};
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Types
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- /*** Windows ***/
- typedef struct /* This clever little structure contains */
- { /* pointers to routines for each type of event. */
- UpdateProc wUpdate;
- ClickProc wClick;
- GrowProc wGrow;
- KeyProc wKey;
- CloseProc wClose;
- DeathProc wDeath;
- ActivateProc wActivate;
- DeactivateProc wDeactivate;
- LoopyProc wLoopy;
- WindowPtr wWindow;
- Ptr wGlobals;
- } WindowObject, *WindowObjectPtr;
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Globals
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- WindowObject WindowObjectList[WMax]; /* Maximum of 30 controlled windows */
- short WindowCount = 0; /* Number of windows defined */
-
- /*** Menus ***/
- MenuHandle MenuHandleList[MMax]; /* MenuHandles indexed by MenuID's */
- IFP MenuProcs[MMax][MIMax]; /* Array of procedures to call from menus */
- short MenuCount; /* How many menus defined */
- short MenuItemCount; /* How many items in last menu */
- MenuHandle MenuEdit; /* Which one is the edit menu? */
-
- /*** Application Edit Commands ***/
- IFP AppUndo,AppCut,AppCopy,AppPaste,AppClear;
-
- /*** Global Status ***/
- Boolean gQuitApp = false;
- long gLastMenuSelect = 0;
-
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // prototypes
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- void InitToolbox(void);
- void DoMyAbout(void);
- void BEUndo(void);
- void BECut(void);
- void BECopy(void);
- void BEPaste(void);
- void BEClear(void);
- void BENull(void);
- void DefaultUpdate(Ptr globals);
- void DefaultClick(Ptr globals, Point p, short mods, long when);
- void DefaultGrow(Ptr globals, Point p, short mods);
- void DefaultKey(Ptr globals, long k, short mods);
- void DefaultClose(Ptr globals);
- void DefaultDeath(Ptr globals);
- void DefaultActivate(Ptr globals);
- void DefaultDeactivate(Ptr globals);
- void DefaultLoopy(Ptr globals);
- void pnull(void);
- void MenuPoint(long theclick);
- void DoKeyPress(long k);
- void MenuClick(Point p);
- void StartMenus(void);
- void InstallMenu(Str255 s);
- void InstallItem(Str255 s, IFP action);
- void InstallEditMenu(IFP Xundo, IFP Xcut, IFP Xcopy, IFP Xpaste, IFP Xclear);
- void EnableMenu(MenuHandle menu, short item, Boolean enable);
- void EnDis(MenuHandle m, short i, short f);
- void EnDisEdits(short Eundo, short Ecut, short Ecopy, short Epaste, short Eclear);
- void DoMouseClick(EventRecord *event);
- void DoGrowWindow(WindowPtr window, EventRecord *event);
- void DoZoomWindow(WindowPtr window, short part);
- void ResizeWindow(WindowPtr window);
- void GetLocalUpdateRgn(WindowPtr window, RgnHandle localRgn);
- Ptr InstallWindow(Rect *iRect, short iType, Boolean iGoway, unsigned char *iTitle, UpdateProc iUpdate, ClickProc iClick, GrowProc iGrow, KeyProc iKey, CloseProc iClose, DeathProc iDeath, ActivateProc iActivate, DeactivateProc iDeactive, LoopyProc iLoopy, long iGlobalsSize, WindowPtr *thisWindowPtr);
- Ptr GetInstallWindow(short windID, UpdateProc iUpdate, ClickProc iClick, GrowProc iGrow, KeyProc iKey, CloseProc iClose, DeathProc iDeath, ActivateProc iActivate, DeactivateProc iDeactive, LoopyProc iLoopy, long iGlobalsSize, WindowPtr *thisWindowPtr);
- Ptr InstallDialog(short iResID, ClickProc iClick, CloseProc iClose, long iGlobalsSize, DialogPtr *thisWindowPtr);
- void UninstallWindow(WindowPtr uWindow);
- void UninstallDialog(DialogPtr uDialog);
- void DoCloseWindow(void);
- void DoQuit(void);
- WindowObjectPtr ScanWindowObjectList(WindowPtr w, short *n);
- Ptr GetWindowStorage(WindowPtr w);
- void FrontDA(void);
- GrafPtr SaveGrafPort(GrafPtr newPort);
- void EventLoop(void);
- void DoNew(void);
- void DoOpen(void);
- void DoClose(Ptr storage);
- void main(void);
-
-
- /************************************
- * Some useful routines
- ************************************/
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void InitToolbox(void)
- {
- InitGraf(&qd.thePort);
- InitFonts();
- FlushEvents(0xffff,0);
- InitWindows();
- InitMenus();
- InitDialogs(0);
- TEInit();
- InitCursor();
- }
-
- void CopyStr(Str255 source, Str255 dest)
- {
- BlockMove(source, dest, source[0]+1);
- }
-
- void AppendStr(Str255 source, Str255 dest)
- {
- BlockMove(&source[1], &dest[dest[0]+1], source[0]);
- dest[0] += source[0];
- }
-
- void TrapError(Str255 s, OSErr err, Boolean breakIt, Boolean fatal)
- {
- short i;
- WindowObjectPtr wo;
-
- if (err)
- {
- if (breakIt)
- {
- Str255 errStr;
- Str31 numStr;
-
- CopyStr(s, errStr);
- AppendStr("\p: ", errStr);
- NumToString(err, numStr);
- if ((numStr[0] + errStr[0]) > 255)
- numStr[0] = 255 - errStr[0];
- AppendStr(numStr, errStr);
-
- DebugStr(errStr);
- }
-
- if (fatal)
- {
- wo = WindowObjectList;
- i = WindowCount;
- while (i--)
- (*wo->wDeath)(wo->wGlobals);
-
- ExitToShell();
- }
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DoMyAbout(void)
- {
- SysBeep(1);
- }
-
-
- /************************************
- * Some inherent methods
- ************************************/
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void BEUndo(void)
- {
- if(!SystemEdit(0))
- (*AppUndo)();
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void BECut(void)
- {
- if(!SystemEdit(2))
- (*AppCut)();
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void BECopy(void)
- {
- if(!SystemEdit(3))
- (*AppCopy)();
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void BEPaste(void)
- {
- if(!SystemEdit(4))
- (*AppPaste)();
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void BEClear(void)
- {
- if(!SystemEdit(5))
- (*AppClear)();
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // default routines
-
- void BENull(void){}
- void DefaultUpdate(Ptr globals)
- {
- #pragma unused (globals)
- }
- void DefaultClick(Ptr globals, Point p, short mods, long when)
- {
- #pragma unused (globals, p, mods, when)
- }
- void DefaultGrow(Ptr globals, Point p, short mods)
- {
- #pragma unused (globals, p, mods)
- }
- void DefaultKey(Ptr globals, long k, short mods)
- {
- #pragma unused (globals, k, mods)
- }
- void DefaultClose(Ptr globals)
- {
- #pragma unused (globals)
- }
- void DefaultDeath(Ptr globals)
- {
- #pragma unused (globals)
- }
- void DefaultActivate(Ptr globals)
- {
- #pragma unused (globals)
- }
- void DefaultDeactivate(Ptr globals)
- {
- #pragma unused (globals)
- }
- void DefaultLoopy(Ptr globals)
- {
- #pragma unused (globals)
- }
- void pnull(void) {}
-
- /************************************
- * Menu Action Routines
- ************************************/
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void MenuPoint(long theclick)
- {
- short mID,mItem;
- unsigned char DAname[30];
-
- mID = HiWrd(theclick);
- mItem = LoWrd(theclick);
-
- gLastMenuSelect = theclick; /* save for others to look at */
-
- if(mID == 0)
- return;
-
- if(mID == 1) /* Apple menu */
- {
- if(mItem == 1) /* Its either the about box */
- DoMyAbout();
- else
- { /* Or a DA */
- GetItem(MenuHandleList[1],mItem,DAname);
- OpenDeskAcc(DAname);
- }
- }
- else
- (*MenuProcs[mID][mItem-1])();
-
- HiliteMenu(0);
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DoKeyPress(long k)
- {
- MenuPoint(MenuKey((char)k));
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void MenuClick(Point p)
- {
- MenuPoint(MenuSelect(p));
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Start with just an About box, and some DA's.
-
- void StartMenus(void)
- {
- MenuHandle applemenu;
- applemenu = NewMenu(1,"\p"); /* Apple menu: ID 1 */
- AppendMenu(applemenu,"\pAbout...;(-");
- AddResMenu(applemenu,'DRVR');
- InsertMenu(applemenu,0);
- DrawMenuBar();
- MenuHandleList[1] = applemenu;
-
- MenuCount = 1; /* Next menu added will be ID 2 */
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void InstallMenu(Str255 s)
- /*
- * Start a new menu with name s
- */
- {
- MenuCount++; /* new menu */
- MenuItemCount = 0; /* with no entries */
-
- MenuHandleList[MenuCount] = NewMenu(MenuCount,s);
- InsertMenu(MenuHandleList[MenuCount],0);
- DrawMenuBar();
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void InstallItem(Str255 s, IFP action)
- /*
- * Add an item to the last menu, and associate a routine with it.
- */
- {
- if (MenuItemCount < MIMax) {
- AppendMenu(MenuHandleList[MenuCount],s);
- MenuProcs[MenuCount][MenuItemCount++] = action;
- }
- else
- SysBeep(10);
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void InstallEditMenu(IFP Xundo,IFP Xcut,IFP Xcopy,IFP Xpaste,IFP Xclear)
- /*
- * Start an edit menu, and put the first six things in.
- */
- {
- AppUndo = Xundo;
- AppCut = Xcut;
- AppCopy = Xcopy;
- AppPaste = Xpaste;
- AppClear = Xclear;
-
- InstallMenu("\pEdit");
- InstallItem("\pUndo/Z",BEUndo);
- InstallItem("\p(-",BENull);
- InstallItem("\pCut/X",BECut);
- InstallItem("\pCopy/C",BECopy);
- InstallItem("\pPaste/V",BEPaste);
- InstallItem("\pClear/B",BEClear);
-
- MenuEdit = MenuHandleList[MenuCount];
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Enable or disable any given menu item.
- void EnableMenu(MenuHandle menu, short item, Boolean enable)
- {
- if (enable)
- EnableItem(menu,item);
- else
- DisableItem(menu,item);
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void EnDis(MenuHandle m, short i, short f)
- /*
- * Enable or disable item i of menu m.
- */
- {
- if (f==0)
- DisableItem(m,i);
- else if (f > 0)
- EnableItem(m,i);
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void EnDisEdits(short Eundo,short Ecut,short Ecopy,short Epaste,short Eclear)
- /*
- * For each edit menu entry,
- * 0=disable, 1=enable, -1=leave alone.
- */
- {
- EnDis(MenuEdit,1,Eundo);
- EnDis(MenuEdit,3,Ecut);
- EnDis(MenuEdit,4,Ecopy);
- EnDis(MenuEdit,5,Epaste);
- EnDis(MenuEdit,6,Eclear);
- }
-
-
- /************************************
- * Mouse Action Routines
- ************************************/
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DoMouseClick(EventRecord *event)
- {
- WindowPtr w;
- WindowObjectPtr wo;
- short part;
- short i;
-
- part = FindWindow (event->where, &w);
-
- switch (part)
- {
- case inDesk: /* click on desk */
- break;
-
- case inMenuBar: /* menubar */
- MenuClick(event->where);
- break;
-
- case inSysWindow: /* system window */
- SystemClick(event,w);
- break;
-
- case inContent: /* content region */
-
- if (w != FrontWindow()) /* If clicked on a non-front window, */
- SelectWindow(w); /* bring it to the front. */
- else if (wo = ScanWindowObjectList(w, &i)) /* Click on front window: give click */
- { /* to window's click routine. */
- SetPort(w);
- (*wo->wClick)(wo->wGlobals, event->where, event->modifiers, event->when);
- }
- break;
-
- case inGrow: /* growregion */
- SetPort(w);
- DoGrowWindow(w, event);
- break;
-
- case inDrag: /* drag */
- DragWindow (w,event->where,&bigRect);
- break;
-
- case inGoAway: /* goAway */
- if (TrackGoAway(w,event->where))
- if (wo = ScanWindowObjectList(w, &i))
- (*wo->wClose)(wo->wGlobals);
- break;
- }
- }
-
- void DoGrowWindow( WindowPtr window, EventRecord *event )
- {
- long growResult;
- Rect tempRect;
-
- tempRect = qd.screenBits.bounds; /* set up limiting values */
-
- growResult = GrowWindow(window, event->where, &tempRect);
-
- /* see if it really changed size */
-
- if ( growResult != 0 )
- {
- SizeWindow(window, LoWrd(growResult), HiWrd(growResult), true);
- ResizeWindow(window);
- DrawGrowIcon(window);
- }
- }
-
- void DoZoomWindow( WindowPtr window, short part )
- {
- EraseRect(&window->portRect);
- ZoomWindow(window, part, window == FrontWindow());
- ResizeWindow(window);
- }
-
- void ResizeWindow( WindowPtr window )
- {
- InvalRect(&window->portRect);
- }
-
- void GetLocalUpdateRgn( WindowPtr window, RgnHandle localRgn ) /* Returns the update region in local coordinates */
- {
- CopyRgn(((WindowPeek) window)->updateRgn, localRgn); /* save old update region */
- OffsetRgn(localRgn, window->portBits.bounds.left, window->portBits.bounds.top);
- }
-
-
- /************************************
- * Window Action Routines
- ************************************/
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Ptr InstallWindow(Rect *iRect, short iType, Boolean iGoway, unsigned char *iTitle,
- UpdateProc iUpdate, ClickProc iClick, GrowProc iGrow, KeyProc iKey,
- CloseProc iClose, DeathProc iDeath, ActivateProc iActivate, DeactivateProc iDeactive,
- LoopyProc iLoopy, long iGlobalsSize, WindowPtr *thisWindowPtr)
- /*
- * Add a window to BigEasy's list. If the window is
- * already up somewhere, bring it to the front and
- * visualize it.
- */
- {
- #pragma unused (iGrow)
-
- WindowObject *thisWindow;
- Ptr p = nil;
-
- if (*thisWindowPtr != 0) /* something already assigned to this window? */
- {
- if(!((WindowPeek) *thisWindowPtr)->visible) /* If so, just show it, and bring it to the front. */
- ShowWindow(*thisWindowPtr);
- SelectWindow(*thisWindowPtr);
- return (nil);
- }
-
- thisWindow = &WindowObjectList[WindowCount];
-
- if (HaveCQD())
- {
- p = NewPtrClear(sizeof(CWindowRecord) + iGlobalsSize); /* make room for window record + globals */
- if (p)
- thisWindow->wWindow = NewCWindow(p, iRect, iTitle, true, iType, (WindowPtr) -1, iGoway, 0);
- }
- else
- {
- p = NewPtrClear(sizeof(WindowRecord) + iGlobalsSize); /* make room for window record + globals */
- if (p)
- thisWindow->wWindow = NewWindow(p, iRect, iTitle, true, iType, (WindowPtr) -1, iGoway, 0);
- }
-
- if (!thisWindow->wWindow)
- {
- DisposePtr(p);
- return (nil);
- }
-
- thisWindow->wUpdate = iUpdate;
- thisWindow->wClick = iClick;
- thisWindow->wKey = iKey;
- thisWindow->wClose = iClose;
- thisWindow->wDeath = iDeath;
- thisWindow->wActivate = iActivate;
- thisWindow->wDeactivate = iDeactive;
- thisWindow->wLoopy = iLoopy;
- if (HaveCQD())
- thisWindow->wGlobals = p + sizeof(CWindowRecord);
- else
- thisWindow->wGlobals = p + sizeof(WindowRecord);
-
- WindowCount++;
-
- *thisWindowPtr = thisWindow->wWindow;
- return (thisWindow->wGlobals);
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Ptr GetInstallWindow(short windID,
- UpdateProc iUpdate, ClickProc iClick, GrowProc iGrow, KeyProc iKey,
- CloseProc iClose, DeathProc iDeath, ActivateProc iActivate, DeactivateProc iDeactive,
- LoopyProc iLoopy, long iGlobalsSize, WindowPtr *thisWindowPtr)
-
- {
- Ptr result;
- WindowTHndl windTemplate;
-
- windTemplate = (WindowTHndl) GetResource('WIND', windID);
- if (windTemplate == nil) {
- Debugger();
- return (nil);
- }
-
- HLock((Handle)windTemplate);
- result = InstallWindow(&((**windTemplate).boundsRect),
- (**windTemplate).procID,
- (**windTemplate).goAwayFlag,
- (**windTemplate).title,
- iUpdate, iClick, iGrow, iKey, iClose, iDeath, iActivate,
- iDeactive, iLoopy,
- iGlobalsSize, thisWindowPtr);
- HUnlock ((Handle)windTemplate);
- HPurge ((Handle)windTemplate);
- return (result);
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Ptr InstallDialog(short iResID, ClickProc iClick, CloseProc iClose, long iGlobalsSize, DialogPtr *thisWindowPtr)
- /*
- * Add a dialog to BigEasy's list. If the window is
- * already up somewhere, bring it to the front and
- * visualize it.
- */
- {
- WindowObject *thisWindow;
- Ptr p;
-
- if (*thisWindowPtr != 0) /* something already assigned to this window? */
- {
- if(!((WindowPeek) *thisWindowPtr)->visible) /* If so, just show it, and bring it to the front. */
- ShowWindow((WindowPtr) *thisWindowPtr);
- SelectWindow((WindowPtr) *thisWindowPtr);
- return (nil);
- }
-
-
- thisWindow = &WindowObjectList[WindowCount];
-
- p = NewPtrClear(sizeof(DialogRecord) + iGlobalsSize); /* make room for window record + globals */
-
- thisWindow->wWindow = GetNewDialog(iResID, p, (WindowPtr) -1);
- if (!thisWindow->wWindow)
- {
- DisposePtr(p);
- return (nil);
- }
-
- thisWindow->wUpdate = (UpdateProc) DefaultUpdate;
- thisWindow->wClick = iClick;
- thisWindow->wKey = DefaultKey;
- thisWindow->wClose = iClose;
- thisWindow->wActivate = DefaultActivate;
- thisWindow->wDeactivate = DefaultDeactivate;
- thisWindow->wLoopy = DefaultLoopy;
- thisWindow->wGlobals = p + sizeof(DialogRecord);
-
- WindowCount++;
-
- *thisWindowPtr = (DialogPtr) thisWindow->wWindow;
- return (thisWindow->wGlobals);
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void UninstallWindow(WindowPtr uWindow)
- {
- short i;
-
- if (ScanWindowObjectList(uWindow, &i))
- {
- CloseWindow(uWindow);
- DisposePtr((Ptr) uWindow);
- WindowObjectList[i] = WindowObjectList[--WindowCount];
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void UninstallDialog(DialogPtr uDialog)
- {
- short i;
-
- if (ScanWindowObjectList(uDialog, &i))
- {
- CloseDialog(uDialog);
- DisposePtr((Ptr) uDialog);
- WindowObjectList[i] = WindowObjectList[--WindowCount];
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DoCloseWindow(void)
- {
- WindowPtr w;
- WindowObjectPtr wo;
- short i;
-
- w = FrontWindow();
- if (wo = ScanWindowObjectList(w, &i))
- {
- SetPort(w);
- (*wo->wClose)(wo->wGlobals);
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DoQuit(void)
- {
- short i;
- WindowObjectPtr wo;
-
- wo = WindowObjectList;
- i = WindowCount;
- while (i)
- {
- SetPort(wo->wWindow);
- (*wo->wClose)(wo->wGlobals);
- --i;
- }
-
- gQuitApp = true;
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- WindowObjectPtr ScanWindowObjectList(WindowPtr w, short *n)
- /*
- * Set n to the window number of w, if its there. Return TRUE if
- * the window was found, or FALSE if not.
- */
- {
- short i;
-
- for (i = 0; i < WindowCount; i++)
- if (WindowObjectList[i].wWindow == w)
- {
- *n = i;
- return (&WindowObjectList[i]);
- }
-
- return (nil);
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Ptr GetWindowStorage(WindowPtr w)
- {
- WindowObjectPtr wo;
- short n;
-
- if (wo = ScanWindowObjectList(w, &n))
- return (wo->wGlobals);
- else
- return (nil);
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void FrontDA(void)
- /*
- * Check the front window. If it's a DA,
- * enable all edit menu options.
- */
- {
- WindowPeek window;
-
- window = (WindowPeek)FrontWindow();
- if (window->windowKind < 0) /* Any click in a DA window: */
- EnDisEdits(1,1,1,1,1); /* enable edit menu. */
- }
-
- /************************************
- * Event Routines
- ************************************/
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- GrafPtr SaveGrafPort(GrafPtr newPort)
- {
- GrafPtr oldPort;
-
- GetPort(&oldPort);
- SetPort(newPort);
- return (oldPort);
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void EventLoop(void)
- {
- EventRecord ER;
- short i;
- WindowPtr w;
- WindowObjectPtr wo;
- short item;
- GrafPtr oldPort;
-
- SetCursor(&qd.arrow); // make sure our cursor is the arrow
-
- if ( WaitNextEvent(everyEvent, &ER, kStandardSleep, nil) ) {
-
- if (IsDialogEvent(&ER)) {
- if (DialogSelect(&ER, &w, &item)) {
- if (wo = ScanWindowObjectList(w,&i)) {
- oldPort = SaveGrafPort(wo->wWindow);
- (*wo->wClick)(wo->wGlobals, ER.where, item, ER.when);
- SaveGrafPort(oldPort);
- return;
- }
- }
- }
- }
- else {
-
- // nullEvents come in here only when WaitNextEvent returns false
- // this happens when the sleep time has expired
- wo = WindowObjectList;
- for (i = 0; i < WindowCount; i++) {
- (*wo->wLoopy)(wo->wGlobals);
- wo++;
- }
-
- if (IsDialogEvent(&ER))
- DialogSelect(&ER, &w, &item);
- return;
- }
-
- switch (ER.what)
- {
- case mouseDown: /* mouse down */
- FrontDA();
- DoMouseClick(&ER);
- break;
-
- case keyDown: /* key event */
- case autoKey:
- FrontDA();
- DoKeyPress(ER.message);
- if (wo = ScanWindowObjectList(FrontWindow(), &i))
- (*wo->wKey)(wo->wGlobals, ER.message, ER.modifiers);
- break;
-
- case updateEvt: /* update */
- if (wo = ScanWindowObjectList((WindowPtr) ER.message, &i))
- {
- BeginUpdate((WindowPtr) ER.message);
- SetPort((WindowPtr) ER.message);
- (*wo->wUpdate)(wo->wGlobals);
- EndUpdate((WindowPtr) ER.message);
- }
- break;
-
- case activateEvt: /* activate */
- FrontDA();
- if (wo = ScanWindowObjectList((WindowPtr) ER.message, &i))
- {
- oldPort = SaveGrafPort(wo->wWindow);
- if (ER.modifiers & activeFlag)
- (*wo->wActivate)(wo->wGlobals);
- else
- (*wo->wDeactivate)(wo->wGlobals);
- DrawGrowIcon(wo->wWindow);
- SaveGrafPort(oldPort);
- }
- break;
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DoNew(void)
- {
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DoOpen(void)
- {
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DoClose(Ptr storage)
- {
- #pragma unused (storage)
-
- UninstallWindow(FrontWindow());
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void main(void)
- {
- InitToolbox();
- StartMenus();
-
- Bootstrap(); // start things going
-
- while (!gQuitApp)
- EventLoop();
- }
-